package ajaxjs.config;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.script.ScriptException;
import javax.servlet.http.HttpServletRequest;

import ajaxjs.lang.servletHandler;

/**
 * JSONPath
 * @author sp42
 *
 */
public class Node {
	private HttpServletRequest request;
	@servletHandler
	public Node(HttpServletRequest request){
		this.request = request;
		request.setAttribute("node", this);
	}
	
    /**
     * 读取网站结构中的某个节点
     * @param node /product/app
     */
    public Map<String, Object> getNode(String node){
    	String code = "bf.config.getStru('" + node + "');";
    	Object jsHash = null;
		try {
			jsHash = Application.jsRuntime.eval(code);
		} catch (ScriptException e) {
			ajaxjs.Util.catchException(e, "读取读取网站结构中的节：%s 失败！", code);
			return null;
		}
		
		if(jsHash != null){ 
			Map<String, Object> nodeHash = Application.jsRuntime.NativeObject2Hash(jsHash);
//			System.out.println(nodeHash == null ? "没有节点！" + node : "Looking for the SingleNode:" + node);
			// 子节点的类型转换为  Map<String, Object>[]
//		    if(nodeHash != null && nodeHash.get("children") != null && nodeHash.get("children") instanceof NativeArray){
//		    	nodeHash.put("children", JS_ScriptEngine.getArr(nodeHash.get("children")));
//		    }
			return nodeHash;
		}else {
			System.err.println("没有该节点对象信息！" + node);
			return null;// 忽略节点
		}
    }
    
    /**
     * 读取节点信息，返回 hash 结构（详细信息）
     * ${viewController.node.name}
     * @return
     */
    public Map<String, Object> getNode(){
    	return getNode(getRoute());
    }
    
    /**
     * 读取节点信息，返回 节点的 name / link
     * true: 获取节点的 A 连接：<a href="xxx">xxx</a>
     * false：textNode
     * @return
     */
	public String getNode(boolean isWithLink){
		String route = getRoute(), result = null;

		if(route.equals("/")){
			result = "首页";// 根节点
		}else if(isWithLink){
			String root = request.getContextPath(),
					code = "bf.config.getStru('" + route + "', {"
							+ "isFull : true, isOutputMarkup: true, root : '" + root + "'"
							+ "});";
			
			try {
				result = (String)Application.jsRuntime.eval(code);
			} catch (ScriptException e) {
				e.printStackTrace();
				ajaxjs.Util.catchException(e, "读取节点信息:%s失败！", root);
			}
		}else{
			Map<String, Object> node = getNode();
			
			if(node != null && node.get("name") != null){ // 担心 nullpointer
				result = node.get("name").toString();
			}else{
				
				result = null;
			}
		}

	    request.setAttribute(isWithLink ? "WebsiteNode_link" : "WebsiteNode", result);

		return result;
	}
	
	/**
	 * for el express shorthand
	 * ${viewController.node.nodeLink}
	 * @return
	 */
	public String getNodeLink(){
		return getNode(true);
	}
	
	/**
	 * for el express shorthand
	 * 原本要这样：
	 * ${viewController.node.node.name}
	 * 现在可以这样：
	 * ${viewController.node.name}
	 * @return
	 */
	public String getName(){
		return getNode(false);
	}
	
	/**
	 * 读取完整的路径，相当于把节点扁平化
	 * @param node
	 * @return
	 */
    @SuppressWarnings("unchecked")
	public List<Map<String, Object>> getSiteStru_Node_Flat(String node){
        String code = "bf.config.getStru('" + node + "', {isFull : true});";
       
        try {
			return (List<Map<String, Object>>)Application.jsRuntime.eval(code);
		} catch (ScriptException e) {
			ajaxjs.Util.catchException(e, "读取完整的路径%s失败！", node);
			return null;
		}
    }
   
    /**
     * 读取网站结构中的某个节点其下一级中所有的节点
     * @return
     */
    @SuppressWarnings("rawtypes")
    public HashMap[] getSiteStru_Node_Children(){
		// 读取网站节点
		Map node = getNode();
		return node.get("children") != null ? (HashMap[]) node.get("children") : null;
    }
    @SuppressWarnings("rawtypes")
    public HashMap[] getSiteStru_ParentNode_Children(){
        // 读取网站节点
        String route = getRoute();
       
        String [] strArr = route.split("/");
        strArr[strArr.length - 1] = ""; // 删除最后一个元素
       
        StringBuilder sb = new StringBuilder();
        for(String str : strArr){
        	if(str != null && !str.equals(""))sb.append("/" + str);
        }
        sb.append("/");
       
        String parentNode = sb.toString();
       
        Map node = getNode(parentNode);
        HashMap[] result = node.get("children") != null 
        		? (HashMap[])node.get("children") : null;
       
//          System.out.println("result:"+result);
        return result;
    }
    
	/**
	 * 分析 URL 目标资源（最原始的版本）
	 */
	private String getRoute(){
		String route = request.getRequestURI().replace(request.getContextPath(), "");		
		return route;
	}
	/**
	 * 获取导航
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static List<Map<String, Object>> getNav(){
		 try {
			return (List<Map<String, Object>>)Application.jsRuntime.eval("bf.config.getNav();");
		} catch (ScriptException e) {
			e.printStackTrace();
			ajaxjs.Util.catchException(e, "获取导航失败！");
		}
		return null;
	}

	/*
	 *  页脚的网站地图	
		JS_ScriptEngine js = new JS_ScriptEngine();
	 	String global_SSJS_Path = request.getSession().getServletContext().getRealPath("/WEB-INF/classes/rhino/");
		
	 	js.read_jsFile(global_SSJS_Path + "/common.js");
	 	js.read_jsFile(global_SSJS_Path + "/app/stru.js");
	
	 	js.read_jsFile(request.getSession().getServletContext().getRealPath("/META-INF/site_stru.js"));
	 	out.write(js.eval("bf.jsonPath.makeSiteMap(0, 9)"));
	 */
	public static String getFooter(String root){
		String code = "bf.jsonPath.makeSiteMap('" + root + "')";
		try {
			return Application.jsRuntime.eval(code).toString();
		} catch (ScriptException e) {
			e.printStackTrace();
			ajaxjs.Util.catchException(e, "获取页脚的网站地图失败！");
			return null;
		}
	}
	
	public static String getFooter(HttpServletRequest request){
		return getFooter(request.getContextPath());
	}
}